#!/bin/bash
# 功能:
# 这个脚本用于检查系统环境,并输出各项系统配置的状态,包括操作系统、CPU 架构、网络设置、
# 磁盘使用情况和已安装的软件包等。
# 该脚本适用于基于 Unix 的系统,支持主流 Linux 发行版,如 CentOS、RHEL、Debian、
# Ubuntu、Deepin、Kylin 和 openEuler。
# 作者: zxm
# 创建日期: 2024-12-05
# 版本: v1.3
# 更新内容:
# 1. 优化了 SELinux 状态的检查方法，兼容了 Debian 操作系统，该操作系统默认可能没有安装 sestatus 命令
# 2. select_package_manager 方法中，kylinos 修改为 kylin
# 3. check_selinux 方法中，\$ 修改为 $，去掉 \
# 4. check_cpu_memory 方法中，获取内存的方法修改为 grep MemTotal /proc/meminfo | awk '{printf "%.2f\n", $2 / 1024 / 1024}'

# 定义一个输出红色文本的函数
red() {
    echo -e "\033[31m$1\033[0m"
}

# 检测操作系统类型
detect_os() {
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        OS=$ID
        VER=$VERSION_ID
    elif [ -f /etc/redhat-release ]; then
        OS=$(awk '{print $1}' /etc/redhat-release)
        VER=$(awk '{print $4}' /etc/redhat-release)
    else
        OS=$(uname -s)
        VER=$(uname -r)
    fi
}

# 选择合适的包管理器命令
select_package_manager() {
    case $OS in
    "centos" | "rhel")
        PKG_MGR="rpm -q"
        ;;
    "debian" | "ubuntu")
        PKG_MGR="dpkg -l | grep"
        ;;
    "deepin" | "kylin" | "uos")
        PKG_MGR="dpkg -l | grep"
        ;;
    "openeuler")
        PKG_MGR="rpm -q"
        ;;
    *)
        red "不支持的操作系统: $OS"
        exit 1
        ;;
    esac
}

# 检查主机名和 IP 地址
check_hostname_ip() {
    hostname=$(hostname)
    ip=$(hostname -I | awk '{print $1}')
    if [ "$hostname" == "localhost" ]; then
        red "主机名: $hostname"
    else
        echo "主机名: $hostname"
    fi
    echo "IP 地址: $ip"
}

# 检查操作系统版本
check_os_version() {
    echo "操作系统: $OS"
    echo "版本: $VER"
    kernel_version=$(uname -r)
    echo "内核版本: $kernel_version"
}

# 检查 CPU 架构
check_cpu_arch() {
    cpu_arch=$(uname -m)
    if [ "$cpu_arch" == "aarch64" ]; then
        red "CPU 架构: $cpu_arch (ARM64)"
    elif [ "$cpu_arch" != "x86_64" ]; then
        red "CPU 架构: $cpu_arch"
    else
        echo "CPU 架构: $cpu_arch"
    fi
}

# 检查字符集、时区和当前时间
check_locale_timezone() {
    lang=$LANG
    timezone=$(timedatectl status | grep "Time zone" | awk '{print $3}')
    current_time=$(date +"%Y-%m-%d %H:%M:%S")

    echo "字符集: $lang"
    if [[ "$timezone" != "Asia/Shanghai" ]]; then
        red "时区: $timezone"
    else
        echo "时区: $timezone"
    fi
    echo "当前时间: $current_time"
}

# 检查 NTP（网络时间协议）服务
check_ntp() {
    if ! systemctl is-active --quiet chronyd && ! systemctl is-active --quiet ntpd; then
        red "未配置 NTP 服务"
    else
        echo "NTP 服务已配置"
    fi
}

# 检查 DNS 配置
check_dns() {
    echo "DNS 配置:"
    cat /etc/resolv.conf | grep 'nameserver' | awk '{print "    " $2}'
}

# 检查 CPU 核数和内存大小
check_cpu_memory() {
    cpu_count=$(nproc --all)
    mem_size=$(grep MemTotal /proc/meminfo | awk '{printf "%.2f\n", $2 / 1024 / 1024}')
    echo "CPU 核数: $cpu_count"
    echo "内存大小: ${mem_size}GB"
}

# 检查磁盘分区
check_disk() {
    echo "磁盘分区:"
    echo "    分区                                             容量      挂载点     使用率"
    df -h --output=source,size,target,pcent | grep -v 'overlay' | tail -n +2 | awk '{printf "    %-50s %-10s %-15s %s\n", $1, $2, $3, $4}'
}

# 检查文件句柄数限制
check_file_descriptors() {
    file_descriptor_limit=$(ulimit -n)
    if [ "$file_descriptor_limit" != "65536" ]; then
        red "文件句柄数限制: $file_descriptor_limit"
    else
        echo "文件句柄数限制: $file_descriptor_limit"
    fi
}

# 检查防火墙状态
check_firewall() {
    if command -v firewalld >/dev/null; then
        firewall_status=$(systemctl status firewalld | awk '/Active:/ {print $2}')
        if [ "$firewall_status" = "active" ]; then
            red "防火墙状态: $firewall_status"
        else
            echo "防火墙状态: $firewall_status"
        fi
    else
        echo "防火墙未安装或未使用 firewalld"
    fi
}

# 检查 SELinux 状态
check_selinux() {
    # 检查 sestatus 命令是否存在
    if command -v sestatus >/dev/null 2>&1; then
        selinux_status=$(sestatus | awk '/SELinux status/{print $3}')
    elif [ -f /etc/selinux/config ]; then
        # 如果 sestatus 不存在，尝试从 /etc/selinux/config 文件读取
        selinux_status=$(awk -F= '/^SELINUX=/{print $2}' /etc/selinux/config | tr -d ' ')
    elif [ -f /sys/fs/selinux/enforce ]; then
        # 如果 /etc/selinux/config 不存在，尝试从 /sys/fs/selinux/enforce 文件读取
        enforce_status=$(cat /sys/fs/selinux/enforce)
        if [ "$enforce_status" -eq 1 ]; then
            selinux_status="enforcing"
        else
            selinux_status="permissive"
        fi
    else
        # 如果以上方法都不可用，提示用户
        echo "无法检测 SELinux 状态：未找到 sestatus 命令或相关配置文件"
        return
    fi

    # 输出结果
    if [ "$selinux_status" != "disabled" ]; then
        echo -e "\033[31mSELinux 状态: $selinux_status (非禁用)\033[0m"
    else
        echo "SELinux 状态: $selinux_status"
    fi
}

# 检查必要软件包
check_required_packages() {
    # 检查 gcc 和 g++
    for package in gcc g++; do
        if ! $PKG_MGR $package &>/dev/null; then
            red "$package 未安装"
        else
            echo "$package 已安装"
        fi
    done

    # 检查 MySQL 所需的库
    for package in libaio ncurses-compat-libs; do
        if ! $PKG_MGR $package &>/dev/null; then
            red "$package 未安装"
        else
            echo "$package 已安装"
        fi
    done

    # 检查 JDK/JRE
    if command -v java >/dev/null; then
        java_version=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}')
        if [[ "$java_version" != "1.8"* ]]; then
            red "JDK/JRE 已安装，版本: $java_version"
        else
            echo "JDK/JRE 已安装，版本: $java_version"
        fi
    else
        echo "JDK/JRE 未安装"
    fi
}

# 主程序
detect_os
select_package_manager
check_hostname_ip
check_os_version
check_cpu_arch
check_locale_timezone
check_ntp
check_dns
check_cpu_memory
check_disk
check_file_descriptors
check_firewall
check_selinux
check_required_packages

echo "环境检查完成!"
echo "请关注红色的输出内容，更详细信息参考 https://doc.weixin.qq.com/sheet/e3_AMkAigaPAEUDGNwj4u8SQG9e0kMOH?scode=AEoA3Qe6AAoy0AXhWeAMkAigaPAEU&tab=5rg61k 获取更多信息"
